/*
 * chunk_manager.c
 *
 *  Created on: Mar 2, 2013
 *      Author: duoln
 */

#include <stddefine.h>
#include <logging.h>
#include <vector.h>
#include <emalloc.h>
#include <chunk.h>
#include <map.h>
#include <io.h>
#include "chunk_manager.h"

typedef struct
{
    Map* chunks;
} ChunkManager;

static Logger* mLog = NULL;

static ChunkManager* mManager = NULL;

void chunk_manager_init()
{
    mLog = GET_LOGGER("/lfs/chunksevrer");
    mManager = emalloc(sizeof(ChunkManager));
    mManager->chunks = map_new(MAP_INT64);
}

static inline void build_chunk_file_path(char new_path[], const char* path, int64_t id)
{
#ifdef X86_32
    sprintf(new_path, "%sc.%lld", path, id);
#endif
#ifdef X86_64
    sprintf(new_path, "%sc.%ld", path, id);
#endif
}

Status chunk_manager_chunk_create(const char* path, int64_t id, const char* filename, int32_t size)
{
    //check chunk existing
    char namespace[NAMESPACE_LEN] = { 0 };
    build_chunk_file_path(namespace, path, id);
    if (io_check_file_exist(namespace))
    {
        return LFS_FILE_IS_EXIST;
    }
    Chunk* chunk = NULL;
    if((chunk = chunk_create(namespace, id, filename, size)) == NULL){
        logger(FATAL(mLog), "Can not create chunk '%s'", namespace);
        return LFS_FAIL;
    }
    map_put(mManager->chunks, (void*) &id, chunk);
    return LFS_SUCC;
}

Status chunk_manager_chunk_append(int64_t id, void* data, int32_t size)
{
    Chunk* chunk = NULL;
    if (!map_get(mManager->chunks, (void*) &id, (void**) &chunk))
    {
        return LFS_FILE_NOT_EXIST;
    }
    int re = 0;
    if ((re = chunk_append(chunk, data, size)) != 1)
    {
        if (re == -1)
        {
            return LFS_LACK_OF_RESOURCE;
        }
        else
        {
            return LFS_FAIL;
        }
    }
    return LFS_SUCC;
}

Status chunk_manager_chunk_read(int64_t id, int64_t start, int64_t end, Vector* files)
{
    Chunk* chunk = NULL;
    if (!map_get(mManager->chunks, (void*) &id, (void**) &chunk))
    {
        return LFS_FILE_NOT_EXIST;
    }
    if(!chunk_read(chunk, start, end, files))
    {
        return LFS_FAIL;
    }
    return LFS_SUCC;
}

